#include <iostream>

//c
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>


int main() {
    //打开一个 socket fd, 0 指的是 tcp 协议
    int socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if(socketfd == -1)
        return -1;

    sockaddr_in addrIn;
    addrIn.sin_family = AF_INET;    //ipv4
    inet_pton(AF_INET, "0.0.0.0", &addrIn.sin_addr);
    //addrIn.sin_addr.s_addr = htonl(INADDR_ANY);   //INADDR_ANY 表示使用通配地址
    addrIn.sin_port = htons(SERT_PORT);

    //将 socket fd 绑定到对应的地址中
    if(bind(socketfd, (sockaddr*)(&addrIn), sizeof(sockaddr_in)) == -1)
        return -1;
    
    //监听客户端的连接, 将socket 文件描述符从主动转为被动
    //正在处理客户端请求时, 如果有新的请求进来, 套接字是没法处理的, 只能把它放进缓冲区
    //这个缓冲区用于记录正在连接但是还没有连接完成的客户端
    //如果这个队列满了,服务器就不会理会新的连接请求
    if (listen(socketfd, 4) == -1)
        return -1;

    sockaddr_in cliaddr;
    socklen_t clien(sizeof(sockaddr_in));

    //被动监听客户端发起的 tcp 连接请求, 三次握手后连接建立成功, 并获得客户端的信息
    //此时是阻塞的
    int acceptfd = accept(socketfd, (sockaddr*)(&cliaddr), &clien);
    if (acceptfd == -1)
        return -1;
    
    char recvMsg[MAXLINE + 1] = {0};
    if (read(acceptfd, recvMsg, MAXLINE) != 0)
        std::cout << recvMsg << std::endl;

    write(acceptfd, recvMsg, MAXLINE);
    
    close(acceptfd);
    close(socketfd);

    return 0;
}